home *** CD-ROM | disk | FTP | other *** search
- /* QST.C Copyright (C) 1993 Fergus Patrick Duniho */
-
- #define MAXLINE 256
-
- typedef struct qnode {
- int p[2]; /* Preference Array Numbers */
- int num, ans, strength;
- char *Qtext, *Atext[2];
- struct qnode *pv, *nx;
- } qst;
-
- qst *RND_QList (qst *Q, int size);
- char *Get_QList (char *fname, qst *Q, int size);
- void AskQuestions (qst *Q, int col);
- int AskQ (qst *Q, int col);
- char get_answer(int col);
- qst *new_qnode (int num);
- int get_strength (int col);
-
- qst *new_qnode (int num) {
- qst *node;
-
- if ((node = (qst *)malloc(sizeof(qst))) == NULL) {
- perror ("Malloc can't allocate enough memory for a new qnode.\n");
- exit (2);
- }
- node->ans = -1;
- node->num = num;
- return node;
- }
-
- /* Get_QList: Reads questions from a file into a linked list.
- Returns the version # string from the beginning of the
- questions file. */
-
- char *Get_QList (char *fname, qst *Q, int size) {
- FILE *fptr;
- int i, j;
- char *V;
- qst *S;
-
- S = Q;
- RdOpen (fptr, fname);
- V = clone_line(fptr, MAXLINE);
- for (i = 1; i <= size; i++) {
- Q->nx = new_qnode(i);
- Q->nx->pv = Q;
- Q = Q->nx;
- Q->Qtext = clone_line(fptr, MAXLINE);
- for (j = 0; j < 2; j++) {
- Q->p[j] = fgetp(fptr);
- Q->Atext[j] = clone_line(fptr, MAXLINE);
- }
- }
- fclose (fptr);
- Q->nx = S;
- return V;
- }
-
- /* nth_qnode: Returns the nth member of a linked list of qst nodes. */
-
- qst *nth_qnode (qst *Q, unsigned int n) {
- while (n--)
- Q = Q->nx;
- return Q;
- }
-
- /* RND_QList: Randomizes a linked list of questions. */
-
- qst *RND_QList (qst *Q, int size) {
- qst *S, *L, *N, *SN;
- unsigned int i, j;
- char *temp;
-
- SN = N = new_qnode(0);
- S = Q;
-
- /* Randomizes Answer Order */
- for (i = 0; i < size; i++)
- if (rand() % 2) {
- L = nth_qnode(S, i);
- j = L->p[1]; L->p[1] = L->p[0]; L->p[0] = j;
- temp = L->Atext[1];
- L->Atext[1] = L->Atext[0];
- L->Atext[0] = temp;
- }
-
- /* Randomizes Question Order */
- for (; size; size--) {
- i = (rand() % size) + 1;
- L = nth_qnode(S, i);
- L->nx->pv = L->pv;
- L->pv->nx = L->nx;
- N->nx = L;
- L->pv = N;
- N = L;
- }
- free (S);
- N->nx = SN;
- SN->pv = N;
- return SN;
- }
-
- void AskQuestions (qst *Q, int col) {
- int more = 1, flag = 1, num;
-
- while (more) {
- for (Q = Q->nx, num = 1; Q->num > 0; Q = Q->nx, num++) {
- if ((Q->ans != -1) && flag)
- continue;
- flag = 1;
- printf ("\nQuestion #%d\n", num);
- if (AskQ(Q, col)) {
- Q = Q->pv->pv;
- flag = 0;
- num -= 2;
- if (num < 0) num = 0;
- }
- }
- more = 0;
- for (Q = Q->nx; Q->num > 0; Q = Q->nx)
- if (Q->ans == -1) more = 1;
- }
- }
-
- /* AskQ: Asks a single question. */
-
- int AskQ (qst *Q, int col) {
- char A;
-
- wrapwrite (stdout, 0, 0, col, Q->Qtext, 0);
- wrapwrite (stdout, 0, 4, col, "(A)", Q->Atext[0], 0);
- puts (" ... Or");
- wrapwrite (stdout, 0, 4, col, "(B)", Q->Atext[1], 0);
- if ((A = get_answer(col)) < 2) {
- Q->ans = Q->p[A];
- Q->strength = get_strength(col);
- }
- else if (A == 4)
- exit (2);
- return A == 3;
- }
-
- char get_answer(int col) {
- char c;
-
- for (;;) {
- c = fgetc(stdin);
- while (fgetc(stdin) != '\n');
- if (islower(c))
- c = toupper(c);
- if (c == 'A')
- return 0;
- if (c == 'B')
- return 1;
- if (c == 'S')
- return 2;
- if (c == 'P')
- return 3;
- if (c == 'Q')
- return 4;
- wrapwrite (stdout, 0, 0, col,
- "Answer with an A or a B.\n",
- "P = Go back to Previous question\n",
- "Q = Quit\n",
- "S = Skip until later.\n", 0);
- }
- }
-
- int get_strength (int col) {
- int i;
- wrapwrite (stdout, 0, 0, col, "Please rate the strength of this",
- "preference on a scale of 1 to 7.\n",
- "1 = Faint\n",
- "2 = Weak\n",
- "3 = Modest\n",
- "4 = Moderate\n",
- "5 = Strong\n",
- "6 = Extreme\n",
- "7 = Excessive\n", 0);
- for (;;) {
- i = fgetp(stdin);
- if (i < 8)
- break;
- wrapwrite (stdout, 0, 0, col,
- "Please select a number from 1 to 7.", 0);
- }
- return i;
- }
-